/**
 *
 */
package de.cbf.cam.dsa.person.entities;

import de.cbf.cam.dsa.item.model.entities.interfaces.IGenderSpecific;
import de.cbf.cam.dsa.person.generator.entities.NameData;
import de.cbf.cam.dsa.rcp.model.entities.MonthDSAEnum;
import de.cbf.cam.dsa.rcp.model.entities.ProfessionLevel;
import de.cbf.util.uuidheader.entities.UUIDReference;
import de.cbf.util.uuidheader.entities.UUIDHeader;
import de.cbf.util.uuidheader.exceptions.EntityMergeException;

/**
 * @author Surfer
 *
 */
public class PersonBaseDSA extends UUIDHeader implements IGenderSpecific,Cloneable{

	public static final String P_TITLE 					= "title";
	public static final String P_FIRST_NAME 			= "firstName";
	public static final String P_NAME_ADD 				= "name_add";
	public static final String P_SUR_NAME 				= "sur_name";
	public static final String P_HEIGTH 				= "heigth";
	public static final String P_WEIGHT 				= "weight";
	public static final String P_RACE 					= "chosenRace";
	public static final String P_CULTURE 				= "chosenCulture";
	public static final String P_PROFESSION				= "chosenProfession";
	public static final String P_BIRTH_DAY 				= "birth_day";
	public static final String P_BIRTH_MONTH 			= "birth_month";
	public static final String P_BIRTH_YEAR 			= "birth_year";
	public static final String P_LOOKS 					= "looks";
	public static final String P_HAIR 					= "hair";
	public static final String P_EYES 					= "eyes";
	public static final String P_CHARACTER_SPECIALS		= "character_specials";
	public static final String P_PROFESSION_LEVEL 		= "profession_level";
	public static final String P_GENDER 				= "gender";

	public static final int PI_TITLE 				=  0;
	public static final int PI_FIRST_NAME 			=  1;
	public static final int PI_NAME_ADD 			=  2;
	public static final int PI_SUR_NAME 			=  3;
	public static final int PI_BIRTH_DAY 			=  4;
	public static final int PI_BIRTH_MONTH 			=  5;
	public static final int PI_BIRTH_YEAR 			=  6;
	public static final int PI_RACE 				=  7;
	public static final int PI_CULTURE 				=  8;
	public static final int PI_PROFESSION 			=  9;
	public static final int PI_EYES 				= 10;
	public static final int PI_HAIR 				= 11;
	public static final int PI_HEIGTH 				= 12;
	public static final int PI_WEIGHT 				= 13;
	public static final int PI_CHARACTER_SPECIALS 	= 14;
	public static final int PI_LOOKS 				= 15;
	public static final int PI_PROFESSION_LEVEL 	= 16;
	public static final int PI_GENDER 				= 17;

	protected int gender							= -1;

	protected NameData 	nameData 					= null;

	protected int birthday							=	 0;
	protected MonthDSAEnum birthmonth				= null;
	protected Long birthyear						=    0L;
	/** in "Stein" (kg)*/
	protected float weight							=	 0;
	/**	 * in "Halbfinger" (cm)	 */
	protected float height							=	 0;

	protected UUIDReference chosenRace				= null;
	protected UUIDReference chosenCulture			= null;
	protected UUIDReference chosenProfession		= null;
	protected ProfessionLevel professionLevel		= null;

	protected PersonSpecialsDSA			specials 	= null;
	protected PersonEyesDSA 			eyes		= null;
	protected PersonHairDSA 			hair		= null;
	protected PersonLooksDSA 			looks		= null;
	protected PersonItemsDSA			items 		= null;


	public PersonBaseDSA() {
		super();
	}

	@Override
	protected void doMergeDataFrom(UUIDHeader entity, boolean i_am_older)
			throws EntityMergeException {
		throw new EntityMergeException("Not implemented!");

	}

	public Integer ageForYear(Object object) {
		Integer result = 0;
		Long longAge = 0L;
		if (object instanceof Long) {
			Long year = (Long) object;
			longAge = year-birthyear;
			if(longAge >= 0 && longAge < Integer.MAX_VALUE){
				result = longAge.intValue();
			}
		}
		return result;
	}

	@Override
	public String toString() {
		StringBuffer buffer = new StringBuffer();
		if(nameData != null){
			buffer.append(nameData.getNameString());
		}
		buffer.append("\n");
		buffer.append(birthday);
		buffer.append(".");
		if(birthmonth != null){
			buffer.append(birthmonth.toString());
		}else{
			buffer.append("0");
		}
		buffer.append(".");
		buffer.append(birthyear);
		buffer.append("\n(");
		if(chosenRace != null){
			buffer.append(chosenRace.getSavedName());
		}
		buffer.append(",");
		if(chosenCulture != null){
			buffer.append(chosenCulture.getSavedName());
		}
		buffer.append(",");
		if(chosenProfession != null){
			buffer.append(chosenProfession.getSavedName());
			if(professionLevel != null){
				buffer.append("[");
				buffer.append(professionLevel.getName());
				buffer.append("]");
			}
		}
		buffer.append(")");
		if(specials != null){
			buffer.append("\n");
			buffer.append(specials.specialString());
		}
		if(items != null){
			buffer.append("\n");
			buffer.append(items.itemString());
		}
		return buffer.toString();
	}


	public Object clone() throws CloneNotSupportedException{
		PersonBaseDSA clonePerson = new PersonBaseDSA();

		clonePerson.nameData = nameData;
		clonePerson.birthday = birthday;
		clonePerson.birthmonth = birthmonth;
		clonePerson.birthyear = birthyear;
		clonePerson.chosenRace = (UUIDReference)chosenRace.clone();
		clonePerson.chosenCulture = (UUIDReference)chosenCulture.clone();
		clonePerson.chosenProfession =  (UUIDReference) chosenProfession.clone();
		clonePerson.specials = (PersonSpecialsDSA)specials.clone();
		clonePerson.eyes = (PersonEyesDSA) eyes.clone();
		clonePerson.hair = (PersonHairDSA) hair.clone();
		clonePerson.looks = (PersonLooksDSA) looks.clone();
		clonePerson.height = height;
		clonePerson.weight = weight;
		return clonePerson;
	}
	@Override
	public int hashCode() {
		final int prime = 31;
		int result = super.hashCode();
		result = prime * result + birthday;
		result = prime * result
				+ ((birthmonth == null) ? 0 : birthmonth.hashCode());
		result = prime * result + (int) (birthyear ^ (birthyear >>> 32));
		result = prime * result + ((chosenCulture == null) ? 0 : chosenCulture.hashCode());
		result = prime * result + ((eyes == null) ? 0 : eyes.hashCode());
		result = prime * result + ((hair == null) ? 0 : hair.hashCode());
		result = prime * result + Float.floatToIntBits(height);
		result = prime * result + ((looks == null) ? 0 : looks.hashCode());
		result = prime * result
				+ ((chosenProfession == null) ? 0 : chosenProfession.hashCode());
		result = prime * result + ((chosenRace == null) ? 0 : chosenRace.hashCode());
		result = prime * result
				+ ((specials == null) ? 0 : specials.hashCode());
		result = prime * result + Float.floatToIntBits(weight);
		return result;
	}

	@Override
	public boolean equals(Object obj) {
		if (this == obj)
			return true;
		if (!super.equals(obj))
			return false;
		if (getClass() != obj.getClass())
			return false;
		PersonBaseDSA other = (PersonBaseDSA) obj;
		if (birthday != other.birthday)
			return false;
		if (birthmonth != other.birthmonth)
			return false;
		if (birthyear != other.birthyear)
			return false;
		if (chosenCulture == null) {
			if (other.chosenCulture != null)
				return false;
		} else if (!chosenCulture.equals(other.chosenCulture))
			return false;
		if (eyes == null) {
			if (other.eyes != null)
				return false;
		} else if (!eyes.equals(other.eyes))
			return false;
		if (hair == null) {
			if (other.hair != null)
				return false;
		} else if (!hair.equals(other.hair))
			return false;
		if (Float.floatToIntBits(height) != Float.floatToIntBits(other.height))
			return false;
		if (looks == null) {
			if (other.looks != null)
				return false;
		} else if (!looks.equals(other.looks))
			return false;
		if (chosenProfession == null) {
			if (other.chosenProfession != null)
				return false;
		} else if (!chosenProfession.equals(other.chosenProfession))
			return false;
		if (chosenRace == null) {
			if (other.chosenRace != null)
				return false;
		} else if (!chosenRace.equals(other.chosenRace))
			return false;
		if (specials == null) {
			if (other.specials != null)
				return false;
		} else if (!specials.equals(other.specials))
			return false;
		if (Float.floatToIntBits(weight) != Float.floatToIntBits(other.weight))
			return false;
		return true;
	}

	public String getWholeDisplayName(){
		if(nameData != null){
			return nameData.getNameString();
		}
		return "";
	}

	public NameData getNameData() {
		return nameData;
	}

	public void setNameData(NameData nameData) {
		this.nameData = nameData;
	}

	public int getBirthday() {
		return birthday;
	}
	public void setBirthday(int birthday) {
		if(this.birthday == birthday){
			return;
		}
		int oldbirthday = this.birthday;
		this.birthday = birthday;
		propertyChangeSupport.fireIndexedPropertyChange(P_BIRTH_DAY,
			PI_BIRTH_DAY, oldbirthday, this.birthday);
	}



	public MonthDSAEnum getBirthmonth() {
		return birthmonth;
	}
	public void setBirthmonth(MonthDSAEnum birthmonth) {
		if(this.birthmonth != null && this.birthmonth .equals( birthmonth)){
			return;
		}
		MonthDSAEnum oldbirthmonth = this.birthmonth;
		this.birthmonth = birthmonth;
		propertyChangeSupport.fireIndexedPropertyChange(P_BIRTH_MONTH,
			PI_BIRTH_MONTH, oldbirthmonth, this.birthmonth);
	}

	public Long getBirthyear() {
		return birthyear;
	}
	public void setBirthyear(Long birthyear) {
		if(this.birthyear == birthyear){
			return;
		}
		long oldbirthyear = this.birthyear;
		this.birthyear = birthyear;
		propertyChangeSupport.fireIndexedPropertyChange(P_BIRTH_YEAR,
			PI_BIRTH_YEAR, oldbirthyear, this.birthyear);
	}



	public UUIDReference getRace() {
		return chosenRace;
	}
	public void setRace(UUIDReference race) {
		if(this.chosenRace != null && this.chosenRace .equals( race)){
			return;
		}
		UUIDReference oldrace = this.chosenRace;
		this.chosenRace = race;
		propertyChangeSupport.fireIndexedPropertyChange(P_RACE,
			PI_RACE, oldrace, this.chosenRace);
	}



	public UUIDReference getCulture() {
		return chosenCulture;
	}
	public void setCulture(UUIDReference culture) {
		if(this.chosenCulture != null && this.chosenCulture.equals( culture)){
			return;
		}
		UUIDReference oldculture = this.chosenCulture;
		this.chosenCulture = culture;
		propertyChangeSupport.fireIndexedPropertyChange(P_CULTURE,
			PI_CULTURE, oldculture, this.chosenCulture);
	}



	public UUIDReference getProfession() {
		return chosenProfession;
	}
	public void setProfession(UUIDReference profession) {
		if(this.chosenProfession != null && this.chosenProfession.equals( profession)){
			return;
		}
		UUIDReference oldprofession = this.chosenProfession;
		this.chosenProfession = profession;
		propertyChangeSupport.fireIndexedPropertyChange(P_PROFESSION,
			PI_PROFESSION, oldprofession, this.chosenProfession);
	}

	public PersonSpecialsDSA getSpecials() {
		return specials;
	}

	public void setSpecials(PersonSpecialsDSA specials) {
		if(this.specials != null && this.specials.equals( specials)){
			return;
		}
		PersonSpecialsDSA oldspecials = this.specials;
		this.specials = specials;
		propertyChangeSupport.fireIndexedPropertyChange(P_CHARACTER_SPECIALS,
			PI_CHARACTER_SPECIALS, oldspecials, this.specials);
	}



	public PersonEyesDSA getEyes() {
		return eyes;
	}
	public void setEyes(PersonEyesDSA eyes) {
		if(this.eyes != null && this.eyes.equals( eyes)){
			return;
		}
		PersonEyesDSA oldeyes = this.eyes;
		this.eyes = eyes;
		propertyChangeSupport.fireIndexedPropertyChange(P_EYES,
			PI_EYES, oldeyes, this.eyes);
	}



	public PersonHairDSA getHair() {
		return hair;
	}
	public void setHair(PersonHairDSA hair) {
		if(this.hair != null && this.hair .equals( hair)){
			return;
		}
		PersonHairDSA oldhair = this.hair;
		this.hair = hair;
		propertyChangeSupport.fireIndexedPropertyChange(P_HAIR,
			PI_HAIR, oldhair, this.hair);
	}



	public PersonLooksDSA getLooks() {
		return looks;
	}
	public void setLooks(PersonLooksDSA looks) {
		if(this.looks .equals( looks)){
			return;
		}
		PersonLooksDSA oldlooks = this.looks;
		this.looks = looks;
		propertyChangeSupport.fireIndexedPropertyChange(P_LOOKS,
			PI_LOOKS, oldlooks, this.looks);
	}

	public float getWeight() {
		return weight;
	}
	public void setWeight(float weight) {
		if(this.weight == weight){
			return;
		}
		float oldweight = this.weight;
		this.weight = weight;
		propertyChangeSupport.fireIndexedPropertyChange(P_WEIGHT,
			PI_WEIGHT, oldweight, this.weight);
	}

	public float getHeight() {
		return height;
	}
	public void setHeight(float height) {
		if(this.height == height){
			return;
		}
		float oldheight = this.height;
		this.height = height;
		propertyChangeSupport.fireIndexedPropertyChange(P_HEIGTH,
			PI_HEIGTH, oldheight, this.height);
	}

	public ProfessionLevel getProfessionLevel() {
		return professionLevel;
	}

	public void setProfessionLevel(ProfessionLevel professionLevel) {
		if(this.professionLevel == professionLevel){
			return;
		}
		ProfessionLevel oldProfessionLevel = this.professionLevel;
		this.professionLevel = professionLevel;
		propertyChangeSupport.fireIndexedPropertyChange(P_PROFESSION_LEVEL,
			PI_PROFESSION_LEVEL, oldProfessionLevel, this.professionLevel);
	}

	public int getGender() {
		return gender;
	}

	public void setGender(int gender) {
		if(this.gender == gender){
			return;
		}
		int oldGender = this.gender;
		this.gender = gender;
		propertyChangeSupport.fireIndexedPropertyChange(P_GENDER,
			PI_GENDER, oldGender, this.gender);
	}

	public PersonItemsDSA getItems() {
		return items;
	}

	public void setItems(PersonItemsDSA items) {
		this.items = items;
	}







}
